package com.matt.service.impl;

//import com.alibaba.fastjson.JSON;
import com.aliyun.openservices.shade.com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.ImmutableMap;
import com.aliyun.openservices.shade.org.apache.commons.lang3.StringUtils;
import com.matt.commons.exception.BusinessException;
import com.matt.commons.utils.MapConvertUtil;
import com.matt.commons.utils.RemoteCallUtil;
import com.matt.controller.po.ChildrenPO;
import com.matt.domain.Children;
import com.matt.domain.WorkDate;
import com.matt.foundation.dto.teach.ChildDTO;
import com.matt.foundation.dto.teach.ChildrenNurseryRecordDTO;
import com.matt.foundation.dto.teach.ClassDTO;
import com.matt.foundation.dto.teach.EarlyChangeRecordDTO;
import com.matt.foundation.model.ErrorCode;
import com.matt.foundation.model.StatusResponse;
import com.matt.foundation.utils.HttpClientUtil;
import com.matt.foundation.utils.ModelUtil;
import com.matt.service.TeachCallService;
import lombok.extern.slf4j.Slf4j;
//import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.assertj.core.util.Lists;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

import static com.matt.commons.constant.CommonConstant.AUTH_VALUE;
import static com.matt.foundation.model.ErrorCode.TEACH_SERVER_ERROR;

/**
 * *******************************
 * Created by Ron.
 * form com.matt
 * on 2018/7/26
 * *******************************
 */
@Service
@Slf4j
public class TeachCallServiceImpl implements TeachCallService {

    @Value("${teach.server.url}")
    private String teachServerUrl;


    @Override
    public boolean addChild(String crmClienteleId, String childrenName, String nickName, Integer gender, String birthday, String areaId, String address, String name, String phone, String company, String relation, String staffId) {
        try {
            if (null == gender){
                gender = 0;  //确保一定有性别
            }

            Map params = ModelUtil.mapOf(
                    Lists.newArrayList("crmClienteleId", "childrenName", "nickName", "gender", "birthday", "areaId", "address", "name", "phone", "company", "relation", "staffId"),
                    Lists.newArrayList(crmClienteleId, childrenName, nickName, gender, birthday, areaId, address, name, phone, company, relation, staffId));
            String responseJson = HttpClientUtil.sendPost(teachServerUrl + "/api/other_system/create_child", params, AUTH_VALUE).toString();
            StatusResponse statusResponse = ModelUtil.objectMapper.readValue(responseJson, StatusResponse.class);
            if (statusResponse.getCode().equals(ErrorCode.SUCCESSFUL))
                return true;
            throw new BusinessException(statusResponse.getCode(), statusResponse.getMassage());
        } catch (IOException e) {
            log.info("教务系统创建宝宝出错");
            throw new BusinessException(TEACH_SERVER_ERROR, "教务系统创建宝宝出错");
        }
    }

    @Override
    public boolean activeChild(String clienteleId, String contractBeginDate, String contractEndDate, String productJson) {
        try {
            Map params = ModelUtil.mapOf(Lists.newArrayList("clienteleId", "contractBeginDate", "contractEndDate", "productJson"), Lists.newArrayList(clienteleId, contractBeginDate, contractEndDate, productJson));
            String responseJson = HttpClientUtil.sendPost(teachServerUrl + "/api/other_system/active_child", params, AUTH_VALUE).toString();
            StatusResponse statusResponse = ModelUtil.objectMapper.readValue(responseJson, StatusResponse.class);
            if (statusResponse.getCode().equals(ErrorCode.SUCCESSFUL))
                return true;
            throw new BusinessException(TEACH_SERVER_ERROR, "教务系统激活宝宝课程出错");
        } catch (IOException e) {
            e.printStackTrace();
            log.info("教务系统激活宝宝课程出错");
            throw new BusinessException(TEACH_SERVER_ERROR, "教务系统激活宝宝课程出错");
        }
    }

    @Override
    public boolean overAllNurseryContract(String clienteleId, String remark, String staffId) {
        try {
            Map params = ModelUtil.mapOf(Lists.newArrayList("clienteleId", "remark", "staffId"), Lists.newArrayList(clienteleId, remark, staffId));
            String responseJson = HttpClientUtil.sendPost(teachServerUrl + "/api/other_system/over_all_nursery_contract", params, AUTH_VALUE).toString();
            StatusResponse statusResponse = ModelUtil.objectMapper.readValue(responseJson, StatusResponse.class);
            if (statusResponse.getCode().equals(ErrorCode.SUCCESSFUL))
                return true;
            throw new BusinessException(statusResponse.getCode(), statusResponse.getMassage());
        } catch (IOException e) {
            log.info("教务系统结束所有托班课程失败");
            throw new BusinessException(TEACH_SERVER_ERROR, "教务系统结束所有托班课程失败");
        }
    }

    @Override
    public boolean overAllEarlyContract(String clienteleId, String remark, String staffId) {
        try {
            Map params = ModelUtil.mapOf(Lists.newArrayList("clienteleId", "remark", "staffId"), Lists.newArrayList(clienteleId, remark, staffId));
            String responseJson = HttpClientUtil.sendPost(teachServerUrl + "/api/other_system/over_all_early_contract", params, AUTH_VALUE).toString();
            StatusResponse statusResponse = ModelUtil.objectMapper.readValue(responseJson, StatusResponse.class);
            if (statusResponse.getCode().equals(ErrorCode.SUCCESSFUL))
                return true;
            throw new BusinessException(statusResponse.getCode(), statusResponse.getMassage());
        } catch (IOException e) {
            log.info("教务系统结束所有早教课程失败");
            throw new BusinessException(TEACH_SERVER_ERROR, "教务系统结束所有早教课程失败");
        }
    }

    @Override
    public boolean overEarlyContract(String clienteleId, int count, String remark, String staffId) {
        try {
            Map params = ModelUtil.mapOf(Lists.newArrayList("clienteleId", "count", "remark", "staffId"), Lists.newArrayList(clienteleId, count, remark, staffId));
            String responseJson = HttpClientUtil.sendPost(teachServerUrl + "/api/other_system/over_early_contract", params, AUTH_VALUE).toString();
            StatusResponse statusResponse = ModelUtil.objectMapper.readValue(responseJson, StatusResponse.class);
            if (statusResponse.getCode().equals(ErrorCode.SUCCESSFUL))
                return true;
            throw new BusinessException(statusResponse.getCode(), statusResponse.getMassage());
        } catch (IOException e) {
            log.info("教务系统减去早教课程失败");
            throw new BusinessException(TEACH_SERVER_ERROR, "教务系统减去早教课程失败");
        }
    }

    @Override
    public boolean updateNurseryLimitCount(String paramJson, String date) {
        try {
            Map params = ModelUtil.mapOf(Lists.newArrayList("paramJson", "date"), Lists.newArrayList(paramJson, date));
            String responseJson = HttpClientUtil.sendPost(teachServerUrl + "/api/other_system/nurser_limit_count", params, AUTH_VALUE).toString();
            StatusResponse statusResponse = ModelUtil.objectMapper.readValue(responseJson, StatusResponse.class);
            if (statusResponse.getCode().equals(ErrorCode.SUCCESSFUL))
                return true;
            throw new BusinessException(statusResponse.getCode(), statusResponse.getMassage());
        } catch (IOException e) {
            log.info("教务系统更新各园区额定床位失败");
            throw new BusinessException(TEACH_SERVER_ERROR, "教务系统更新各园区额定床位失败");
        }
    }

    @Override
    public Long findCountByClienteleIds(String clienteleIds,String date) {
      try {
        Map params = ModelUtil.mapOf("clienteleIds",clienteleIds,"date",date);
        String responseJson = HttpClientUtil.sendPost(teachServerUrl + "/api/other_system/get_clientele_check_in_count", params, AUTH_VALUE).toString();
        StatusResponse statusResponse = ModelUtil.objectMapper.readValue(responseJson, StatusResponse.class);
        if (statusResponse.getCode().equals(ErrorCode.SUCCESSFUL))
            return Long.parseLong(statusResponse.getData().toString());
        throw new BusinessException(statusResponse.getCode(), statusResponse.getMassage());
    } catch (IOException e) {
        log.info("查询客户的宝宝的签到数失败");
        throw new BusinessException(TEACH_SERVER_ERROR, "教务系统查询宝宝的签到数失败");
    }
    }

	@Override
	public boolean updateChildInfo(String areaId, String clienteleId, String childName, boolean freeze) {
		try {
			Map params = ModelUtil.mapOf("clienteleId",clienteleId,"areaId",areaId);
			params.put("childName", childName);
			params.put("freeze", freeze);
			String responseJson = HttpClientUtil.sendPost(teachServerUrl + "/api/other_system/update_child_info", params, AUTH_VALUE).toString();
			 StatusResponse statusResponse = ModelUtil.objectMapper.readValue(responseJson, StatusResponse.class);
		        if (statusResponse.getCode().equals(ErrorCode.SUCCESSFUL))
		            return true;
		        throw new BusinessException(statusResponse.getCode(), statusResponse.getMassage());
		} catch (IOException e) {
			log.info("冻结合同修改宝宝状态以及班级关系失败");
	        throw new BusinessException(TEACH_SERVER_ERROR, "冻结合同修改宝宝状态以及班级关系失败");
		}
	}

    @Override
    public boolean notifyPayOrder(String areaId, String clienteleId, String childrenName, String teacherName,
                                  String orderTitle, String amount, String payType,
                                  Integer rt, String rid){
        try {
            Map params = ModelUtil.mapOf("clienteleId",clienteleId,"areaId",areaId);

            params.put("teacherName", teacherName);
            params.put("orderTitle", orderTitle);
            params.put("amount", amount);
            params.put("resourceType", rt);
            params.put("resourceId", rid);

            if (StringUtils.isNotBlank(payType)) {
                params.put("payType", payType);
            }
            String responseJson = HttpClientUtil.sendPost(teachServerUrl + "/api/other_system/notify_pay_order", params, AUTH_VALUE).toString();
            StatusResponse statusResponse = ModelUtil.objectMapper.readValue(responseJson, StatusResponse.class);
            if (statusResponse.getCode().equals(ErrorCode.SUCCESSFUL))
                return true;
            throw new BusinessException(statusResponse.getCode(), statusResponse.getMassage());
        } catch (IOException e) {
            log.info("推送账单信息失败");
            throw new BusinessException(TEACH_SERVER_ERROR, "推送账单信息失败");
        }
    }

    @Override
    public List<ChildDTO> getChildClassList(String ticket, Integer category, String name, String classId, List<String> crmClienteleIds){

        Map params = ModelUtil.mapOf("category",category);
        if (StringUtils.isNotBlank(name)){
            params.put("childName", name);
        }
        if (StringUtils.isNotBlank(classId)){
            params.put("classId", classId);
        }
        if (crmClienteleIds != null && crmClienteleIds.size() > 0){
            params.put("crmClienteleIds", String.join("|", crmClienteleIds));
        }

        String URL = teachServerUrl + "/api/web/children/list_for_crmV2";

        List<ChildDTO> children = RemoteCallUtil.callOfList(URL, params, ticket, ChildDTO.class, "查询客户班级信息失败");

        return children;
    }

    @Override
    public List<ClassDTO> getClassList(String ticket, Integer category){
        Map params = ModelUtil.mapOf("category",category);

        String URL = teachServerUrl + "/api/web/classes/list_by_area";

        List<ClassDTO> classes = RemoteCallUtil.callOfList(URL, params, ticket, ClassDTO.class, "查询园区班级列表失败");

        return classes;
    }

    @Override
    public Long findCheckInCountByDateAndClienteleId(String ticket,String clienteleId, Date beginDate, Date endDate) {
            try {
                Map params = ModelUtil.mapOf("clienteleId",clienteleId,"beginDate",beginDate);
                params.put("endDate", endDate);
                String URL = teachServerUrl + "/api/other_system/get_clienteleId_check_in_count";
                Integer count = RemoteCallUtil.call(URL, params, ticket, Integer.class, "查询园区班级列表失败");
                return Long.valueOf(count);
            } catch (Exception e) {
                log.info("查询客户的宝宝的签到数失败");
                throw new BusinessException(TEACH_SERVER_ERROR, "教务系统查询宝宝的签到数失败");
            }
    }

    @Override
    public Long findLeaveCountByDateAndClienteleId(String ticket,String clienteleId, Date beginDate, Date endDate) {
        try {
            Map params = ModelUtil.mapOf("clienteleId",clienteleId,"beginDate",beginDate);
            params.put("endDate", endDate);
            String URL = teachServerUrl + "/api/other_system/get_clienteleId_leave_count";
            Integer count = RemoteCallUtil.call(URL, params, ticket, Integer.class, "查询园区班级列表失败");
            return Long.valueOf(count);
        } catch (Exception e) {
            log.info("查询客户的宝宝的签到数失败");
            throw new BusinessException(TEACH_SERVER_ERROR, "教务系统查询宝宝的签到数失败");
        }
    }

    @Override
    public boolean addCameraTime(String clienteleId, Integer month, Integer day) {
        try {
            Map params = ImmutableMap.of("crmClienteleId",clienteleId, "month", month, "day", day);

            String responseJson = HttpClientUtil.sendPost(teachServerUrl + "/api/other_system/add_camera_time", params, AUTH_VALUE).toString();
            StatusResponse statusResponse = ModelUtil.objectMapper.readValue(responseJson, StatusResponse.class);
            if (statusResponse.getCode().equals(ErrorCode.SUCCESSFUL))
                return true;
            throw new BusinessException(statusResponse.getCode(), statusResponse.getMassage());
        } catch (IOException e) {
            log.info("添加摄像头时间失败");
            throw new BusinessException(TEACH_SERVER_ERROR, "添加摄像头时间失败");
        }
    }


    @Override
    public ChildDTO childrenIdByChildren(String childrenId) {

        try {
            Map params = ModelUtil.mapOf("childrenId",childrenId);

            String responseJson = HttpClientUtil.sendPost(teachServerUrl + "/api/other_system/childrenId_by_children", params, AUTH_VALUE).toString();
            StatusResponse statusResponse = ModelUtil.objectMapper.readValue(responseJson, StatusResponse.class);
            if (statusResponse.getCode().equals(ErrorCode.SUCCESSFUL))
                return MapConvertUtil.mapToObject((Map)statusResponse.getData(), ChildDTO.class);
            throw new BusinessException(statusResponse.getCode(), statusResponse.getMassage());
        } catch (IOException e) {
            log.info("查询学生失败");
            throw new BusinessException(TEACH_SERVER_ERROR, "查询学生失败");
        }
    }

    @Override
    public List<WorkDate> getWorkDateList(String beginDate, String endDate){
        String URL = teachServerUrl + "/api/web/workDate/getList";
        Map params = ModelUtil.mapOf("beginDate",beginDate,"endDate",endDate);
        String responseJson = null;
        try {
            responseJson = HttpClientUtil.sendPost(URL, params, AUTH_VALUE).toString();
            StatusResponse statusResponse = ModelUtil.objectMapper.readValue(responseJson, StatusResponse.class);
            if (statusResponse.getCode().equals(ErrorCode.SUCCESSFUL)){
                List<Map<String, Object>> list = (List)statusResponse.getData();
                return (List)list.stream().map((o) -> {
                    return MapConvertUtil.mapToObject(o, WorkDate.class);
                }).collect(Collectors.toList());
            }
            throw new BusinessException(statusResponse.getCode(), statusResponse.getMassage());
        } catch (IOException e) {
            e.printStackTrace();
        }

        return new ArrayList<>();
    }

    @Override
    public List<ChildrenNurseryRecordDTO> getNurseryRecords(String clienteleId, String beginDate, String endDate){
        String URL = teachServerUrl + "/api/other_system/nursery_reocrds";
        Map params = ModelUtil.mapOf("beginDate",beginDate,"endDate",endDate);
        params.put("clienteleId",clienteleId);

        String responseJson = null;
        try {
            responseJson = HttpClientUtil.sendPost(URL, params, AUTH_VALUE).toString();
            StatusResponse statusResponse = ModelUtil.objectMapper.readValue(responseJson, StatusResponse.class);
            if (statusResponse.getCode().equals(ErrorCode.SUCCESSFUL)){
                List<Map<String, Object>> list = (List)statusResponse.getData();
                return (List)list.stream().map((o) -> {
                    return MapConvertUtil.mapToObject(o, ChildrenNurseryRecordDTO.class);
                }).collect(Collectors.toList());
            }
            throw new BusinessException(statusResponse.getCode(), statusResponse.getMassage());
        } catch (IOException e) {
            e.printStackTrace();
        }

        return new ArrayList<>();
    }

    @Override
    public List<EarlyChangeRecordDTO> getEarlyRecords(String clienteleId, String beginDate, String endDate){
        String URL = teachServerUrl + "/api/other_system/early_records";

        Map params = ModelUtil.mapOf("beginDate",beginDate,"endDate",endDate);
        params.put("clienteleId",clienteleId);

        String responseJson = null;
        try {
            responseJson = HttpClientUtil.sendPost(URL, params, AUTH_VALUE).toString();
            StatusResponse statusResponse = ModelUtil.objectMapper.readValue(responseJson, StatusResponse.class);
            if (statusResponse.getCode().equals(ErrorCode.SUCCESSFUL)){

                List<Map<String, Object>> list = (List)statusResponse.getData();

                return list.stream().map((o) -> {
                    return MapConvertUtil.mapToObject(o, EarlyChangeRecordDTO.class);
                }).collect(Collectors.toList());
            }
            throw new BusinessException(statusResponse.getCode(), statusResponse.getMassage());
        } catch (IOException e) {
            e.printStackTrace();
        }

        return new ArrayList<>();
    }

    @Override
    // 修改返回类型为 String（返回宝宝ID）
    public String addByLeads(String ticket, ChildrenPO po) {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        System.out.println("po======================="+po);
        HttpPost httpPost = new HttpPost(teachServerUrl + "/api/v2/child/addByLeadByCrm");

        try {
            // 1. 设置请求头
            httpPost.setHeader("Content-Type", "application/json;charset=utf-8");
            httpPost.setHeader("ticket", ticket);

            // 2. 序列化请求体
            String jsonBody = JSON.toJSONString(po);
            StringEntity entity = new StringEntity(jsonBody, "UTF-8");
            httpPost.setEntity(entity);

            // 3. 执行请求
            CloseableHttpResponse response = httpClient.execute(httpPost);
            HttpEntity responseEntity = response.getEntity();
            String responseJson = EntityUtils.toString(responseEntity, "UTF-8");

            // 4. 检查HTTP状态码
            if (response.getStatusLine().getStatusCode() != 200) {
                throw new BusinessException("999999", "远程接口调用失败，HTTP状态码：" + response.getStatusLine().getStatusCode());
            }

            // 5. 解析响应（核心：配置ObjectMapper忽略未知字段）
            ObjectMapper objectMapper = new ObjectMapper();
            // 关键配置：忽略JSON中不存在于Children类中的字段（如"deleted"）
            objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

            StatusResponse statusResponse = objectMapper.readValue(responseJson, StatusResponse.class);

            if (statusResponse.getCode().equals(ErrorCode.SUCCESSFUL)) {
                // 转换响应数据为Children对象（此时会忽略"deleted"等未知字段）
                Children createdChild = objectMapper.convertValue(
                        statusResponse.getData(),
                        Children.class
                );

                if (createdChild == null || createdChild.getId() == null) {
                    throw new BusinessException("999999", "远程接口未返回宝宝ID");
                }
                return createdChild.getId();
            } else {
                throw new BusinessException(statusResponse.getCode(), statusResponse.getMassage());
            }

        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            log.error("教务系统创建宝宝出错", e);
            throw new BusinessException(TEACH_SERVER_ERROR, "教务系统创建宝宝出错");
        } finally {
            try {
                httpClient.close();
            } catch (Exception e) {
                log.warn("关闭HTTP客户端失败", e);
            }
        }
    }
}
